<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>一场由dagger2引发的一些思考 | 海晨忆的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
  <meta name="description" content="&amp;emsp;&amp;emsp;用了好几年的dagger2，从dagger2.android。就只有当时刚开始用dagger的时候深入的了解过，后来就再也没有深入的时候研究过。这几天又研究了一下，做个总结。 &amp;emsp;&amp;emsp;就拿之前写的kotlin的框架来说，它用的是dagger2.android。从dagger2.android。最明显的就是，需要我们自己写的东西越来越少了，框架帮我们做的事情越">
<meta property="og:type" content="article">
<meta property="og:title" content="一场由dagger2引发的一些思考">
<meta property="og:url" content="https://haichenyi.com/2019/07/31/一场由dagger2引发的一些思考/index.html">
<meta property="og:site_name" content="海晨忆的博客">
<meta property="og:description" content="&amp;emsp;&amp;emsp;用了好几年的dagger2，从dagger2.android。就只有当时刚开始用dagger的时候深入的了解过，后来就再也没有深入的时候研究过。这几天又研究了一下，做个总结。 &amp;emsp;&amp;emsp;就拿之前写的kotlin的框架来说，它用的是dagger2.android。从dagger2.android。最明显的就是，需要我们自己写的东西越来越少了，框架帮我们做的事情越">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-07-31/内存分配1.png">
<meta property="og:updated_time" content="2019-09-18T09:09:44.039Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="一场由dagger2引发的一些思考">
<meta name="twitter:description" content="&amp;emsp;&amp;emsp;用了好几年的dagger2，从dagger2.android。就只有当时刚开始用dagger的时候深入的了解过，后来就再也没有深入的时候研究过。这几天又研究了一下，做个总结。 &amp;emsp;&amp;emsp;就拿之前写的kotlin的框架来说，它用的是dagger2.android。从dagger2.android。最明显的就是，需要我们自己写的东西越来越少了，框架帮我们做的事情越">
<meta name="twitter:image" content="https://haichenyi.com/uploads/article/2019-07-31/内存分配1.png">
  
    <link rel="alternate" href="/atom.xml" title="海晨忆的博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/uploads/artistic_image/head.jpg">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/css/highlight.css">
  <script>
  let antiquityStorage = window.sessionStorage.getItem('antiquitySessionStorage');
  if (antiquityStorage == '' || antiquityStorage == null) {
    var antiquityLoader = '<div id="loaderbox"><div class="loader"><div class="load-roll"><div class="load-top"></div><div class="load-right"></div><div class="load-bottom"></div></div></div></div>';
    document.write(antiquityLoader);
    document.body.style.overflow = 'hidden'
  }
  </script>
</head>

<body>
  <div id="fullpage" class="mobile-nav-right">
    
      <div id="wrapper" style="background-image: url(/uploads/artistic_image/bg.jpg)" title="背景图片来自网络">
    
    
      <header id="header">
  <div id="nav-toggle" class="nav-toggle"></div>
  <div class="head-box global-width">
    <nav class="nav-box nav-right">
      
        <a class="nav-item" href="/" title
        
        >首页</a>
      
        <a class="nav-item" href="/archives" title
        
        >归档</a>
      
        <a class="nav-item" href="/about" title
        
        >简历</a>
      
    </nav>
  </div>
</header>
      <div id="middlecontent" title class="global-width sidebar-left">
        <section id="main"><article id="post-一场由dagger2引发的一些思考" class="article global-container article-type-post" itemscope itemprop="blogPost">
  
    <header class="article-header">
      
  
    <h1 class="article-title" itemprop="name">
      一场由dagger2引发的一些思考
    </h1>
  

    </header>
  
  <div class="article-meta">
    <a href="/2019/07/31/一场由dagger2引发的一些思考/" class="article-date">
  <time datetime="2019-07-31T09:40:23.000Z" itemprop="datePublished">2019-07-31</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Android-常用功能/">Android -常用功能</a>
  </div>

    
  </div>
  
    <span id="busuanzi_container_page_pv">
      本文总阅读量<span id="busuanzi_value_page_pv"></span>次
    </span>
  

  <div class="article-inner">
    
    <div class="article-content article-content-cloud doorframe mac" itemprop="articleBody">
      
        <p>&emsp;&emsp;用了好几年的dagger2，从dagger2.android。就只有当时刚开始用dagger的时候深入的了解过，后来就再也没有深入的时候研究过。这几天又研究了一下，做个总结。</p>
<p>&emsp;&emsp;就拿之前写的<a href="https://github.com/haichenyi/KotlinMvp" target="_blank" rel="noopener">kotlin的框架</a>来说，它用的是dagger2.android。从dagger2.android。最明显的就是，需要我们自己写的东西越来越少了，框架帮我们做的事情越来越多了，以至于，我们对这个过程越来越看不懂了。也就有了我这篇博客。</p>
 <a id="more"></a>
<p>先说这嵌入过程吧。</p>
<h3 id="1-依赖"><a href="#1-依赖" class="headerlink" title="1.依赖"></a>1.依赖</h3><div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">//dagger2_start</span><br><span class="line">def dagger = &quot;2.23.2&quot;</span><br><span class="line">implementation &quot;com.google.dagger:dagger-android:$dagger&quot;</span><br><span class="line">implementation &quot;com.google.dagger:dagger-android-support:$dagger&quot; // if you use the support libraries</span><br><span class="line">kapt &quot;com.google.dagger:dagger-android-processor:$dagger&quot;</span><br><span class="line">implementation &quot;com.google.dagger:dagger:$dagger&quot;</span><br><span class="line">kapt &quot;com.google.dagger:dagger-compiler:$dagger&quot;</span><br><span class="line">//dagger2_end</span><br></pre></td></tr></table></figure></div>
<h3 id="2-DaggerApplication"><a href="#2-DaggerApplication" class="headerlink" title="2.DaggerApplication"></a>2.DaggerApplication</h3><p>&emsp;&emsp;新建类AppMoudle，并用注解@Moudle标记，暂时先不添加任何内容</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">@Module</span><br><span class="line">class AppModule &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;新建接口AppComponent，并实现AndroidInjector<t>接口，泛型先空着，添加如下代码：</t></p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">@Singleton</span><br><span class="line">@Component(modules = [AndroidSupportInjectionModule::classAppModule::class])</span><br><span class="line">interface AppComponent : AndroidInjector&lt;MyApp&gt; &#123;</span><br><span class="line"></span><br><span class="line">    @Component.Builder</span><br><span class="line">    abstract class Builder : AndroidInjector.Builder&lt;MyApp&gt;()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;这里的MyAPP是我们下面新建的Application</p>
<p>&emsp;&emsp;新建MyApp，继承DaggerApplication并实现它的抽象方法，添加如下代码：</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">class MyApp : DaggerApplication() &#123;</span><br><span class="line"></span><br><span class="line">    override fun applicationInjector(): AndroidInjector&lt;out DaggerApplication&gt; =</span><br><span class="line">        DaggerAppComponent.builder().create(this)</span><br><span class="line"></span><br><span class="line">    override fun onCreate() &#123;</span><br><span class="line">        super.onCreate()</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;这个时候，你的项目应该报错，因为你没有DaggerAppComponent这个类，你现在编译一遍，应该就是能生成</p>
<h3 id="DaggerAppCompatActivity"><a href="#DaggerAppCompatActivity" class="headerlink" title="DaggerAppCompatActivity"></a>DaggerAppCompatActivity</h3><p>&emsp;&emsp;让你的BaseActivity类，继承这个DaggerAppCompatActivity</p>
<p>&emsp;&emsp;新建ActComponent接口，并且实现AndroidInjector<t>接口，泛型传你的BaseActivity，如下：</t></p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">@Subcomponent(modules = [AndroidSupportInjectionModule::class])</span><br><span class="line">interface ActComponent : AndroidInjector&lt;BaseActivity&lt;BasePresenter&lt;BaseView&gt;&gt;&gt; &#123;</span><br><span class="line">    @Subcomponent.Builder</span><br><span class="line">    abstract class Builder : AndroidInjector.Builder&lt;BaseActivity&lt;BasePresenter&lt;BaseView&gt;&gt;&gt;()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;新建AllActivityModule类，添加如下代码：</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">@Module(subcomponents = [ActComponent::class])</span><br><span class="line">abstract class AllActivitiesModule &#123;</span><br><span class="line">    @ContributesAndroidInjector</span><br><span class="line">    internal abstract fun contributeMainActivityInjector(): MainActivity</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;这个MainActivity是你的主页面，并且继承你的BaseActivity。</p>
<p>&emsp;&emsp;至此，配置就完成了，你就可以像之前一样，用@Inject标记构造方法，然后，定义变量的地方用@Inject就可以直接用了。</p>
<p><strong>PS:</strong> 我这里用的kotlin，kotlin参数默认是private，dagger2需要参数是public，这里需要加上JvmField注解。并且，要var类型，不能val，因为，val不能二次赋值。如下：</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">@JvmField</span><br><span class="line">@Inject</span><br><span class="line">var presenter: P? = null</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;我们之前用dagger2，没有用dagger2.android的时候，application和activity并不是实现的DaggerApplication，DaggerAppCompatActivity这两个，我们做了很多额外的操作，现在，我们都没有做了，为什么一样可以能运行？因为，我们之前做的额外的操作，现在都是这两个继承的类帮我们做了，可以点进去看一下源码。</p>
<h3 id="引发的思考"><a href="#引发的思考" class="headerlink" title="引发的思考"></a>引发的思考</h3><p>&emsp;&emsp;如标题，引发的思考是什么呢？它这个注解到底是怎么做到的呢？</p>
<h4 id="问，这里为什么会分AppComponent，ActivityComponent，FragmentComponent，写一个component不好吗？"><a href="#问，这里为什么会分AppComponent，ActivityComponent，FragmentComponent，写一个component不好吗？" class="headerlink" title="问，这里为什么会分AppComponent，ActivityComponent，FragmentComponent，写一个component不好吗？"></a>问，这里为什么会分AppComponent，ActivityComponent，FragmentComponent，写一个component不好吗？</h4><p>&emsp;&emsp;<strong><em>答：</em></strong> 我不知道对不对，我的理解是：与整个APP生命周期同步即放在AppComponent中，与Activity生命周期同步即放在ActComponent中，<br>与Fragment生命周期同步即放在FragComponent中。</p>
<p>&emsp;&emsp;从这里引申出什么问题呢？那就是生命周期，我的<a href="https://github.com/haichenyi/KotlinMvp" target="_blank" rel="noopener">kotlin框架</a>整个生命周期都有处理，框架的README也有说明。说到生命周期同步，就要说到不同步，不同步造成的结果就是内存泄漏，至于常见的什么情况下回造成内存泄漏我就不说了，想到内存泄漏，就联想到了内存，想到内存，我就想到了内存分配。这就是我想说的，内存分配。</p>
<h4 id="内存分配"><a href="#内存分配" class="headerlink" title="内存分配"></a>内存分配</h4><p>&emsp;&emsp;说到内存分配，我们就先说三个名词：<strong>栈，堆，方法区</strong></p>
<ol>
<li>栈：存放变量的引用</li>
<li>堆：存放new的对象，堆是最占内存的</li>
<li>方法区：存储字节码信息(类，方法等等字节码)，常量，静态变量等等。常量池在方法区中</li>
</ol>
<p>举个栗子：<strong>String b = new String(“a”)</strong> 和 <strong>String c = “a”</strong>，他们内存是怎么分配的？如图：</p>
<p><img src="/uploads/article/2019-07-31/内存分配1.png" alt="内存分配1.png"></p>
<ol>
<li>等于号左边 <strong>String b，String c</strong>这里的b，c都是引用，所以放在栈中。栈存放引用</li>
<li>等于号右边，new的过程，就是在堆中创建内存的过程，这里的0x123456789就是我们常说的内存地址</li>
<li>常量池里面才是放字符串a</li>
</ol>
<p>&emsp;&emsp;很多面试题都会出这个问题，<strong>b==c和b.equal(a)</strong> ，他们两个的结果结果都知道，前面是false，后面是true。<strong>==</strong> 比较的是整个对象，而<strong>equals</strong>比较的是值。这里b指向的是堆内存中的地址，这个地址才是指向常量池中的字符串a，而c是直接指向常量池中的字符串a</p>
<p>&emsp;&emsp;想多说一句就是 <strong>==</strong> 是怎么比较物理地址的呢？通过比较hashCode的值，在java中是获取不到地址的，不过Object中有个identityHashCodeNative方法，它虽然不是地址，但你可以理解为一个地址对应一个值，这个值就能过identityHashCodeNative来获取，具体怎么算了，这是个native方法我们不知道。不过没关系，只要知道一个地址对应一个值就行了，地址相同这个值就相同。而hashCode默认就是返回这个值，那么如果我们重写了hashCode,按我们的规则来写，可以达到不同的地址，hashCode的值相同，从而得到两个不同的地址用==比较是相同的。</p>
<p>&emsp;&emsp; <strong>PS:</strong> 我们平时说的 <strong><em>把某某对象置为空，释放内存。这种说法是错误的。</em></strong> 比方说这里，b=null，首先，我们只是把某个对象的引用置为空，并不是把某个对象置为空。释放内存，是java的GC回收机制，释放内存，并不是我们释放内存。当GC扫描到，某个对象没有引用指向它了，它就会释放这个对象占用的内存。说到这里，就又想到GC回收机制与强软弱虚四大引用</p>
<h4 id="GC回收和强软弱虚四大引用"><a href="#GC回收和强软弱虚四大引用" class="headerlink" title="GC回收和强软弱虚四大引用"></a>GC回收和强软弱虚四大引用</h4><p><strong>强软弱虚四大引用</strong></p>
<p>&emsp;&emsp; 其实我也不知道说啥，就是上面理解了内存分配，这里再看这几句话，应该印象更加深刻一些。</p>
<ol>
<li>强引用：不论什么情况下，GC回收机制扫描到强引用，都不会管，如果内存不足，则抛出OOM异常</li>
<li>软引用(SoftReference)：GC回收机制扫描到软引用时，当内存足够的时候，不会管，当内存不足的时候，则会回收对应内存</li>
<li>弱引用(WeakReference)：不论什么情况下，只要GC回收机制扫描到弱引用，都会回收对应的内存。</li>
<li>虚引用(PhantomReference)：顾名思义，形同虚设，前面三种都是与生命周期相关，而虚引用不会决定对象的生命周期，如果，一个对象仅持有虚引用，那这个对象就跟没有引用是一样的，不管什么时候，GC回收机制扫描到了这个对象，都有可能会回收对应的内存。为什么说是有可能呢？虚引用必须和引用队列连用，当GC回收机制扫描到一个对象，并准备回收它的时候，发现它还存在虚引用，那么，GC会把这个虚引用先加入到与它关联的引用队列中。所以，当GC发现一个对象有虚引用，并且，这个虚引用已经存在与之关联的引用队列当中了，就会回收这个对象。</li>
</ol>
<p>&emsp;&emsp; GC回收机制判断是否回收内存，都是先判断对象的引用是否存在，引用存放在栈中。</p>
<p><strong>GC回收机制</strong></p>
<p>&emsp;&emsp; 说到GC回收机制，就先聊聊JVM堆的相关知识，一说要JAVA虚拟机，那就要聊聊java是跨平台语言了，它是怎么实现跨平台的呢？</p>
<p>&emsp;&emsp; java程序是跨平台的语言，它是怎么实现跨平台的？</p>
<p>&emsp;&emsp;java程序依赖于JVM（java虚拟机），java程序必须运行在JVM上，JVM是用C、C++开发的，不同的平台是不同的JVM，但是，不管是什么类型的JVM都能运行java程序，这就是所谓的java跨平台。但是，不同JVM编译java程序生成的字节码是一样的，但是编译生成的机器码是不一样的，所以跨平台的是java程序，而不是编译生成的机器码。</p>
<p>&emsp;&emsp;JVM堆，也就是我们上面那个图的堆，JVM堆分为三部分</p>
<ol>
<li>新域：也就是年轻代，分为三部分，一部分：Eden，另两个部分是辅助空间分别是：From Space，To Space</li>
<li>旧域：也就是老年代</li>
<li>永久域：从配置角度看，永久域是独立于JVM的，大小为4M</li>
</ol>
<p>&emsp;&emsp;程序员无法手动释放内存，只能释放引用，内存释放只能由GC释放，程序员可以手动触发GC：<strong><em>System.gc()，</em></strong> 或者是当内存不够用的时候，GC会自动启动，或者是APP空闲的时候，也会启动回收机制。</p>
<p>&emsp;&emsp;GC执行的过程：</p>
<ol>
<li>新建的对象都首先存放在Eden中，如果对象太大，可能直接进入老年代，也就是旧域中。</li>
<li>GC开始执行，都是从Eden或者是From Space把对象copy到To Space中，至于中间的算法，有好几种，标记算法，标记幸存次数，还有复制算法，具体怎么实现的，我不知道。当把对象移动到To Spce之后，此时的To Space变成了From Space，之前的From Space变成了To Space。然后，继续循环</li>
<li>循环一次次数之后，对象达到了移动到旧域的条件，就把对象移动到旧域。</li>
<li>最后，GC就会释放旧域的对象所占用的内存</li>
</ol>
<p>PS：以上都是个人观点，不保证完全正确，没有漏洞。</p>

      
    </div>
    
      <footer class="article-footer">
        完
      </footer>
    
  </div>
  
    
<nav id="article-nav">
  <div class="article-nav-block">
    
      <a href="/2019/07/31/dagger2整个流程解析（一）/" id="article-nav-newer" class="article-nav-link-wrap">
        <strong class="article-nav-caption"></strong>
        <div class="article-nav-title">
          
            dagger2整个流程解析（一）
          
        </div>
      </a>
    
  </div>
  <div class="article-nav-block">
    
      <a href="/2019/07/25/Tomcat安装与启动/" id="article-nav-older" class="article-nav-link-wrap">
        <div class="article-nav-title">Tomcat安装与启动</div>
        <strong class="article-nav-caption"></strong>
      </a>
    
  </div>
</nav>

    
  
  
</article>
</section>
        <aside id="sidebar">
  
    <div class="widget-box">
  <div class="avatar-box avatar-item">
    <img class="avatar" src="/uploads/artistic_image/head.jpg" title="头像来自网络"></img>
    <h3 class="avatar-name">
      
        海晨忆
      
    </h3>
    <p class="avatar-slogan">
      先谋生，再谋爱。人间值得，未来可期。
    </p>
  </div>
</div>


  
    
  <div class="widget-box">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Android-Socket/">Android -Socket</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-加密算法/">Android -加密算法</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-常用功能/">Android -常用功能</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-框架/">Android -框架</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-源码解析/">Android -源码解析</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-自定义view/">Android -自定义view</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-设计模式/">Android -设计模式</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/JAVA-并发/">JAVA -并发</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Java-SpringBoot/">Java -SpringBoot</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Tomcat/">Tomcat</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/kotlin/">kotlin</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库-JDBC/">数据库 -JDBC</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库-MySQL/">数据库 -MySQL</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-box">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/07/">July 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/10/">October 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/09/">September 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/07/">July 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/10/">October 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/05/">May 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">March 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/02/">February 2018</a></li></ul>
    </div>
  </div>

  
    
  <div class="widget-box">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/07/27/JAVA—公平锁，非公平锁，悲观锁，乐观锁，死锁/">JAVA—公平锁，非公平锁，悲观锁，乐观锁，死锁</a>
          </li>
        
          <li>
            <a href="/2021/07/19/JAVA—线程同步器AQS/">JAVA—线程同步器AQS</a>
          </li>
        
          <li>
            <a href="/2021/07/07/Android模拟点击/">Android模拟点击</a>
          </li>
        
          <li>
            <a href="/2019/11/27/SpringBoot系列-消息-RabbitMQ-（二十）/">SpringBoot系列-消息(RabbitMQ)（二十）</a>
          </li>
        
          <li>
            <a href="/2019/11/13/SpringBoot系列-Docker（十九）/">SpringBoot系列-Docker（十九）</a>
          </li>
        
      </ul>
    </div>
  </div>

  
      <div class="widget-box">
    <h3 class="widget-title">友情链接</h3>
    <div class="widget">
      
        <a class="hrf" style="display: block;" href="https://github.com/haichenyi" title target='_blank'
        >Github</a>
      
        <a class="hrf" style="display: block;" href="https://www.jianshu.com/u/6077ee440c37" title target='_blank'
        >简书</a>
      
        <a class="hrf" style="display: block;" href="https://blog.csdn.net/qq_27634797" title target='_blank'
        >CSDN</a>
      
    </div>
  </div>

  
</aside>
      </div>
      <footer id="footer">
  <div class="foot-box footers global-width">
    &copy;2017-2021 海晨忆 &nbsp;&nbsp;
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span id="busuanzi_container_site_pv">阁下是第<span id="busuanzi_value_site_pv"></span>个访客</span>
  </div>
</footer>
      <script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script>
if (!window.jQuery) {
var script = document.createElement('script');
script.src = "/js/jquery-2.0.3.min.js";
document.body.write(script);
}
</script>

  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>



    </div>
    <nav id="mobile-nav" class="mobile-nav-box">
  <div class="mobile-nav-img mobile-nav-top"></div>
  
    <a href="/" class="mobile-nav-link">首页</a>
  
    <a href="/archives" class="mobile-nav-link">归档</a>
  
    <a href="/about" class="mobile-nav-link">简历</a>
  
  <div class="mobile-nav-img  mobile-nav-bottom"></div>
</nav>    
  </div>
</body>
</html>